// https://leetcode-cn.com/problems/find-all-anagrams-in-a-string/
// 438. Find All Anagrams in a String
// Given two strings s and p, return an array of all the start indices of
// p's anagrams in s. You may return the answer in any order
function findAnagrams(s: string, p: string): number[] {
    const sLen = s.length;
    const pLen = p.length;

    if (sLen < pLen) return [];

    const result: number[] = [];
    const count = new Array(26).fill(0);

    for (let i = 0; i < pLen; i++) {
        updateArr(count, s[i], 1);
        updateArr(count, p[i], -1);
    }

    let differ = count.filter((item) => item !== 0).length;
    if (differ === 0) {
        result.push(0);
    }

    for (let i = 0; i < sLen - pLen; i++) {
        const head = getNum(count, s[i]);
        if (head === 0) {
            differ++;
        } else if (head === 1) {
            differ--;
        }
        updateArr(count, s[i], -1);

        const tail = getNum(count, s[i + pLen]);
        if (tail === 0) {
            differ++;
        } else if (tail === -1) {
            differ--;
        }
        updateArr(count, s[i + pLen], 1);

        if (differ === 0) {
            result.push(i + 1);
        }
    }

    return result;
}

function updateArr(arr: number[], c: string, diff: number): void {
    arr[getIndex(c)] += diff;
}

function getNum(arr: number[], c: string): number {
    return arr[getIndex(c)];
}

function getIndex(c: string): number {
    return c.charCodeAt(0) - 'a'.charCodeAt(0);
}
